package com.well.register.event.job;

import com.well.register.console.domain.Job;
import com.well.register.console.domain.JobParam;
import com.well.register.console.service.JobExecutorService;
import com.well.register.event.ServerHandler;
import com.well.rpc.model.DoJobHandlerModel;
import com.well.rpc.model.DoJobResponseModel;
import com.well.rpc.model.EventType;
import com.well.rpc.model.RegisterModel;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * job runner
 * </p>
 *
 * @author weedo
 * @since 2022/8/7
 */

@Slf4j
public class WellJobRunner implements Runnable {

    private RegisterModel registerModel;
    private String jobName;
    private JobExecutorService jobExecutorService;
    /* 0：手动 1：自动*/
    private Integer runType;
    /* 集群共享key */
    private volatile int threadKey;

    public WellJobRunner(RegisterModel registerModel, String jobName, Integer runType, JobExecutorService jobExecutorService) {
        this.registerModel = registerModel;
        this.jobName = jobName;
        this.jobExecutorService = jobExecutorService;
        this.runType = runType;
        if (runType == 1) {
            initThreadKey();
        }
    }

    //init ThreadKey
    private void initThreadKey() {
        Job jobInfo = jobExecutorService.getJobInfo(registerModel, jobName);
        if (jobInfo == null) {
            this.threadKey = 0;
            return;
        }
        this.threadKey = jobInfo.getThreadKey();
    }

    @Override
    public void run() {
        Job job = jobExecutorService.getJobInfo(registerModel, jobName);
        if (runType == 1) {
            if (threadKey != job.getThreadKey()) {
                threadKey = job.getThreadKey();
                return;
            }
            job.setThreadKey(job.getThreadKey() + 1);
            job.setUpdateTime(new Date());
            threadKey = job.getThreadKey();
            if (!jobExecutorService.updateJob(job, threadKey - 1)) {
                return;
            }
        }
        DoJobHandlerModel model = new DoJobHandlerModel();
        int id = jobExecutorService.saveExecutorInfo(jobName, registerModel, runType);
        model.setJobName(jobName);
        List<JobParam> jobParams = jobExecutorService.getJobParam(job.getId());
        Map<String, Object> params = model.getParam();
        jobParams.forEach((jobParam) -> {
            params.put(jobParam.getParamKey(), jobParam.getParamValue());
        });
        model.setJobId(id);
        if (!ServerHandler.writeToClient(registerModel, model, EventType.DO_JOB)) {
            ServerHandler.cancelScheduledFuture(registerModel, jobName);
            DoJobResponseModel doJobResponseModel = new DoJobResponseModel();
            doJobResponseModel.setJobId(id);
            doJobResponseModel.setResult(1);
            doJobResponseModel.setMsg("No executor client.");
            jobExecutorService.saveExecutorResult(doJobResponseModel);
        }
    }
}
